package ua.maxicash.service;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ua.maxicash.dao.AppDao;
import ua.maxicash.dao.EmployerDao;
import ua.maxicash.dao.WorkDao;
import ua.maxicash.dao.WorkerDao;
import ua.maxicash.dto.WorkRowJson;
import ua.maxicash.dto.WorkerOnWorkRowJson;
import ua.maxicash.dto.WorkerRowJson;
import ua.maxicash.util.JqgridQuery;
import ua.maxicash.vo.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service("appService")
public class AppServiceImpl implements AppService {

	@Autowired
	EmployerDao employerDao;

	@Autowired
	WorkerDao workerDao;

	@Autowired
	WorkDao workDao;

	@Autowired
	AppDao appDao;

	@Override
	public SystemUser getSystemUserByEmail(String email) {
        return	appDao.getSystemUserByEmail(email);
	}

	@Override
	public Set<Work> getAllWorks() {

		return appDao.getAllWorks();
	}

	@Override
	public Set<Work> getActiveWorks() {

		return appDao.getActiveWorks();

	}

	@Override
	public void subscribeWorker(String emailWorker, Long idWork) {

		// todo protection against double registrating
		Work work = workDao.getWorkById(idWork);
		Worker worker = workerDao.getWorkerByEmail(emailWorker);
		worker.getWorks().add(work);
		workerDao.saveOrUpdateWorker(worker);

	}

    @Override
    public void unsubscribeWorker(String emailWorker, long idWork) {
        Work work = workDao.getWorkById(idWork);
		Worker worker = workerDao.getWorkerByEmail(emailWorker);
		worker.getWorks().remove(work);
		workerDao.saveOrUpdateWorker(worker);
    }

    @Override
	public WorkRowJson convertWorkingDayToJsonDto(WorkingDay workingDay) {

		Work work = workingDay.getWork();

		WorkRowJson row = new WorkRowJson();
		row.setIdWork(work.getIdWork().toString());
		row.setJobType(work.getJobType().getTitle());
		row.setCity(work.getCity().getRuName());
		row.setRegion(work.getCity().getRegion().getRuName());
		row.setCountry(work.getCity().getCountry().getRuName());

		row.setWorkDate(workingDay.getWorkDate().toString());
		row.setStartTime(workingDay.getStartTime().toString());
		row.setEndTime(workingDay.getEndTime().toString());

		row.setWage(work.getWage().toString());
		row.setEmployer(work.getEmployer().getEmail());
		row.setAbout(work.getAbout());

		return row;
	}

	@Override
	public JqgridQuery parseFilters(String query) {

		ObjectMapper mapper = new ObjectMapper();
		JqgridQuery jq = null;
		
		
		try {
			jq = (JqgridQuery) mapper.readValue(query, JqgridQuery.class);
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return jq;
		
	}

	@Override
	public Set<Work> getWorksByJqgridQuery(JqgridQuery jq) {
		
		return appDao.getWorksByJqgridQuery(jq);
	}

	@Override
	public Set<Worker> getAllWorkers() {
		return appDao.getAllWorkers();
		
	}

	@Override
	public Set<Worker> getWorkersByJqgridQuery(JqgridQuery jq) {
		return appDao.getWorkersByJqgridQuery(jq);
	}

	@Override
	public WorkerRowJson convertWorkerToRowJson(Worker worker) {

		WorkerRowJson row = new WorkerRowJson();
		row.setIdWorker(worker.getIdUser().toString());
		//row.setJobType(work.getJobType().getTitle());
		row.setCity(worker.getCity().getRuName());
		row.setEmail(worker.getEmail());
		row.setFirstName(worker.getFirstName());
		row.setLastName(worker.getLastName());
		row.setImage(worker.getEmail());
		row.setAbout(worker.getAbout());
		
		if (worker.getPhone()==null) {
			row.setPhone("");
		} else {
			row.setPhone(worker.getPhone());
		}
		
		if (worker.getSkype()==null) {
			row.setSkype("");
		} else {
			row.setSkype(worker.getSkype());
		}
		
		if (worker.getIcq()==null) {
			row.setIcq("");
		} else {
			row.setIcq(worker.getIcq());
		}
        List<String> jobTypes = new ArrayList<String>();

		for (JobType jt : worker.getJobTypes()) {
             jobTypes.add(jt.getTitle());
        }
		row.setJobTypes(jobTypes);

		return row;
		
	}

	@Override
	public WorkerOnWorkRowJson convertWorkerOnWorkToRowJson(Worker worker) {
		
		WorkerOnWorkRowJson row = new WorkerOnWorkRowJson();
		row.setIdWorker(worker.getIdUser().toString());
		//row.setJobType(work.getJobType().getTitle());
		row.setCity(worker.getCity().getRuName());
		row.setEmail(worker.getEmail());
		row.setFirstName(worker.getFirstName());
		row.setLastName(worker.getLastName());
		row.setImage(worker.getEmail());
		row.setAbout(worker.getAbout());
		
		return row;
	}

	@Override
	public Set<SystemUser> getLikes(Long idUser, Integer amount) {
		return appDao.getLikesOfSystemUser(idUser, amount);
	}

    @Override
    public Set<SystemUser> getAllLikes(String userEmail) {
        return appDao.getAllLikesOfSystemUser(userEmail);
    }

    @Override
    public Set<SystemUser> getAllLikes(Long idUser) {
        return appDao.getAllLikesOfSystemUser(idUser);
    }

    @Override
	public void like(String myEmail, String hisEmail) {
		appDao.like(myEmail, hisEmail);
		
	}

	@Override
	public void saveSystemUser(SystemUser su) {
		
		if (su instanceof Worker) {
			workerDao.saveOrUpdateWorker((Worker)su);
		}
		
		if (su instanceof Employer) {
			employerDao.updateEmployer((Employer)su);
		}
		
	}

    @Override
    public boolean isSubscribed(Worker su, Work work) {

        //todo could cause some problems with lazy loading
        return work.getApplicants().contains(su);

    }

    @Override
    public SystemUser getSystemUserById(Long id) {
        return appDao.getSystemUserById(id);
    }

    @Override
    public void removeFromLikes(Long idUser, Long idLike) {
        appDao.removeFromLikes(idUser,idLike);
    }
}
